package com.keba.lamp.base.manager.common.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapBuilder;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.keba.basic.base.manager.impl.SuperManagerImpl;
import com.keba.basic.cache.redis2.CacheResult;
import com.keba.basic.cache.repository.CachePlusOps;
import com.keba.basic.database.mybatis.conditions.Wraps;
import com.keba.basic.database.mybatis.conditions.query.LbQueryWrap;
import com.keba.basic.echo.properties.EchoProperties;
import com.keba.basic.model.cache.CacheHashKey;
import com.keba.basic.utils.CollHelper;
import com.keba.lamp.base.entity.common.BaseDict;
import com.keba.lamp.base.manager.common.BaseDictManager;
import com.keba.lamp.base.mapper.common.BaseDictMapper;
import com.keba.lamp.common.cache.base.common.BaseDictCacheKeyBuilder;
import com.keba.lamp.common.constant.DefValConstants;
import com.keba.lamp.system.vo.result.system.DefDictItemResultVO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.*;
import java.util.function.Function;

import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.toList;

/**
 * 基础字典
 *
 * @author zuihou
 * @date 2021/10/10 23:03
 */
@RequiredArgsConstructor
@Service
public class BaseDictManagerImpl extends SuperManagerImpl<BaseDictMapper, BaseDict> implements BaseDictManager {

    private final CachePlusOps cachePlusOps;
    private final EchoProperties ips;

    @Override

    @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
    public Map<Serializable, Object> findByIds(Set<Serializable> dictKeys) {
        if (dictKeys.isEmpty()) {
            return Collections.emptyMap();
        }
        Map<Serializable, Object> codeValueMap = MapUtil.newHashMap();
        dictKeys.forEach(dictKey -> {
            Function<CacheHashKey, Map<String, String>> fun = ck -> {
                LbQueryWrap<BaseDict> wrap = Wraps.<BaseDict>lbQ().eq(BaseDict::getParentKey, dictKey).eq(BaseDict::getState, true)
                        .orderByAsc(BaseDict::getSortValue);
                List<BaseDict> list = baseMapper.selectList(wrap);
                if (CollUtil.isNotEmpty(list)) {
                    return CollHelper.uniqueIndex(list, BaseDict::getKey, BaseDict::getName);
                } else {
                    return MapBuilder.<String, String>create().put(DefValConstants.DICT_NULL_VAL_KEY, "无数据").build();
                }
            };
            Map<String, CacheResult<String>> map = cachePlusOps.hGetAll(BaseDictCacheKeyBuilder.builder(dictKey), fun);
            map.forEach((itemKey, itemName) -> {
                if (!DefValConstants.DICT_NULL_VAL_KEY.equals(itemKey)) {
                    codeValueMap.put(StrUtil.join(ips.getDictSeparator(), dictKey, itemKey), itemName.getValue());
                }
            });
        });
        return codeValueMap;
    }

    @Override

    @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
    public Map<String, List<DefDictItemResultVO>> findDictMapItemListByKey(List<String> dictKeys) {
        if (CollUtil.isEmpty(dictKeys)) {
            return Collections.emptyMap();
        }
        LbQueryWrap<BaseDict> query = Wraps.<BaseDict>lbQ().in(BaseDict::getParentKey, dictKeys).eq(BaseDict::getState, true)
                .orderByAsc(BaseDict::getSortValue);
        List<BaseDict> list = super.list(query);
        List<DefDictItemResultVO> voList = BeanUtil.copyToList(list, DefDictItemResultVO.class);

        //key 是类型
        return voList.stream().collect(groupingBy(DefDictItemResultVO::getParentKey, LinkedHashMap::new, toList()));
    }

}
